package protocol

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"log"
	"stick/utils/strBytes"
)

const (
	AcceptSuccess    = "ok"
	ReadFinish       = "finish"
	NoHeartbeat      = 0
	Heartbeat        = 1
	NormalMessage    = 0
	RequestMessage   = 2
	ResponseMessage  = 3
	FileTypeJson     = 1
	FileTypeFile     = 2
	FileTypeText     = 3
	FileTypeName     = 4
	HeartbeatContext = "heartbeat"
	LengthHeader     = 4
)

type Data struct {
	Length      int32
	Heartbeat   byte
	MessageType byte
	FileType    byte
	Content     *string
}

// FileHeaderEncode 请求头编码
//  requestMethod 请求方式 message 信息
func FileHeaderEncode(heartbeat, messageType, fileType byte, message string) ([]byte, error) {
	// 1. 长度
	length := int32(len(message))
	pkg := new(bytes.Buffer)
	err := binary.Write(pkg, binary.BigEndian, length)
	if err != nil {
		return nil, fmt.Errorf("length err=%v", err)
	}

	// 2. 心跳
	err = binary.Write(pkg, binary.BigEndian, heartbeat)
	if err != nil {
		return nil, fmt.Errorf("heartbeat err=%v", err)
	}

	// 3. 请求方式
	err = binary.Write(pkg, binary.BigEndian, messageType)
	if err != nil {
		return nil, fmt.Errorf("messageType err=%v", err)
	}

	// 4. 文件类型
	err = binary.Write(pkg, binary.BigEndian, fileType)
	if err != nil {
		return nil, fmt.Errorf("fileType err=%v", err)
	}

	// 5. 消息
	err = binary.Write(pkg, binary.BigEndian, strBytes.StringToBytes(message))
	if err != nil {
		return nil, fmt.Errorf("message err=%v", err)
	}

	return pkg.Bytes(), nil
}

// FileHeaderDecode  请求头解码
func FileHeaderDecode(reader io.Reader) (data Data, err error) {

	// 1. 获取消息长度
	var length int32
	err = readHeaderReturnInt(LengthHeader, &length, reader)
	if err != nil {
		return
	}

	// 2. 心跳
	var heartbeat byte
	err = readHeaderReturnByte(1, &heartbeat, reader)
	if err != nil {
		return
	}

	// 3. 请求方式
	var messageType byte
	err = readHeaderReturnByte(1, &messageType, reader)
	if err != nil {
		return
	}

	// 4. 文件类型
	var fileType byte
	err = readHeaderReturnByte(1, &fileType, reader)
	if err != nil {
		return
	}

	// 5. 获取消息内容
	messageBuf := make([]byte, length)
	_, err = reader.Read(messageBuf)
	if err != nil {
		return
	}

	//fmt.Printf("data=%v", length, data)
	message := strBytes.BytesToString(messageBuf)
	data.Length = length
	data.Heartbeat = heartbeat
	data.Content = &message
	data.FileType = fileType
	data.MessageType = messageType

	return
}

// length 读字节个数
func readHeaderReturnInt(length int, result *int32, reader io.Reader) error {
	byt := make([]byte, length)
	_, err := reader.Read(byt)
	if err != nil {
		fmt.Printf("readHeaderReturnInt read err=%v\n", err)
		return err
	}

	buf := bytes.NewBuffer(byt)
	err = binary.Read(buf, binary.BigEndian, result)
	if err != nil {
		log.Printf("readHeaderReturnInt err=%v", err)
		return err
	}
	return nil
}

// length 读字节个数
func readHeaderReturnByte(length int, result *byte, reader io.Reader) error {
	byt := make([]byte, length)
	_, err := reader.Read(byt)
	if err != nil {
		fmt.Printf("readHeaderReturnByte read err=%v\n", err)
		return err
	}

	buf := bytes.NewBuffer(byt)
	err = binary.Read(buf, binary.BigEndian, result)
	if err != nil {
		log.Fatalf("readHeaderReturnByte err=%v", err)
		return err
	}
	return nil
}
